<?php
class Forum_Controller_Action
{   
    /**
     * Forum_Controller_Request object wrapping the request environment
     * @var Forum_Controller_Request
     */
    private $_request = null;
    
    /**
     * Forum_Controller_Response object wrapping the response
     * @var Forum_Controller_Response
     */
    private $_response = null;
    
    /**
     * View object
     * @var Forum_View
     */
    public $view;
    
    /**
     * Layout object
     * @var Forum_Layout
     */
    public $layout;

    /**
     * Constuctor. 
     * Sets the request and response objects, initialize view object.
     * 
     * @param Forum_Controller_Request $request
     * @param Forum_Controller_Response $response
     * @return Forum_Controller_Action
     */
    public function __construct(Forum_Controller_Request $request, Forum_Controller_Response $response)
    {
        $this->setRequest($request)
            ->setResponse($response)
            ->initLayout()
            ->initView();
    }
    
    /**
     * @return Forum_Controller_Action
     */
    public function initLayout()
    {
        if (isset($this->layout) && ($this->layout instanceof Forum_Layout)) {
            return $this->layout;
        }
        
        $this->layout = Forum_Layout::getMvcInstance();
        
        return $this;
    }
    
    /**
     * @return Forum_Controller_Action
     */
    public function initView()
    {
        if (isset($this->view) && ($this->view instanceof Forum_View)) {
            return $this->view;
        }
        
        $this->view = new Forum_View(array());
        
        return $this;
    }
    
    /**
     * Appends the required template to responseBody
     * 
     * @param string $action
     * @param string $name
     * @return void
     */
    public function render($action = null, $name = null)
    {
        $script = $this->getViewScript($action);
        
        $this->getResponse()->appendBody($this->view->render($script), $name);
    }
    
    /**
     * Returns path to view script according to current request
     * 
     * @param string $action
     * @return string|throw an Exception
     */
    public function getViewScript($action = null)
    {
        $request = $this->getRequest();
        if (null === $action) {
            $action = $request->getActionName();
        } elseif (!is_string($action)) {
            throw new Exception('Invalid action specifier for view render');
        }

        $action = str_replace('', '-', $action);
        $script = $action . '.phtml';

        $controller = $request->getControllerName();
        $controller = str_replace('', '-', $controller);
        $script = $controller . DIRECTORY_SEPARATOR . $script;

        return $script;
    }
    
    /**
     * Set the Request object
     * 
     * @param Forum_Controller_Request $request
     * @return Forum_Controller_Action Provides fluent interface
     */
    public function setRequest(Forum_Controller_Request $request)
    {
        $this->_request = $request;
        return $this;
    }
    
    /**
     * Return the Request object
     *
     * @return Forum_Controller_Request
     */
    public function getRequest()
    {
        return $this->_request;
    }
    
    /**
     * Set the Response object
     *
     * @param Forum_Controller_Response $response
     * @return Forum_Controller_Action Provides fluent interface
     */
    public function setResponse(Forum_Controller_Response $response)
    {
        $this->_response = $response;
        return $this;
    }
    
    /**
     * Return the Response object
     *
     * @return Forum_Controller_Response
     */
    public function getResponse()
    {
        return $this->_response;
    }
    
    /**
     * Retrieve requested parameters from request
     * 
     * @param string $param
     * @return mixed
     */
    protected function _getParam($param)
    {
        if (!isset($_REQUEST[$param])) {
            return null;
        }
        return $_REQUEST[$param];
    }
    
    /**
     * Retrieve all parameters from request
     * 
     * @return array
     */
    protected function _getAllParams()
    {
        $params = $_REQUEST;
        if (isset($params['route'])) {
            unset($params['route']);
        }
        if (isset($params['PHPSESSID'])) {
            unset($params['PHPSESSID']);
        }
        return $params;
    }
    
    /**
     * Redirects to provided url
     * 
     * @param string $url
     * @param bool $autocomplete
     * @return void
     */
    protected function _redirect($url = '', $autocomplete = true)
    {
        if (true === $autocomplete) {
            $url = Forum_Helper_Url::getInstance()->getUrl($url);
        }
        
        header("Location: {$url}");
        exit();
    }
    
}